home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CPPTASK.ARJ / TSKWPIP.CPP < prev   
C/C++ Source or Header  |  1991-08-21  |  6KB  |  292 lines

  1. /*
  2.    CPPTask - A Multitasking Kernel For C++
  3.  
  4.    Version 1.0 08-12-91
  5.  
  6.    Ported by Rich Smith from:
  7.  
  8.    Public Domain Software written by
  9.       Thomas Wagner
  10.       Patschkauer Weg 31
  11.       D-1000 Berlin 33
  12.       West Germany
  13.  
  14.    TSKWPIP.CPP - Word Pipe handling routines.
  15.  
  16.    Subroutines:
  17.        wpipe::wpipe
  18.        wpipe::~wpipe
  19.        wpipe::read_wpipe
  20.        wpipe::c_read_wpipe
  21.        wpipe::write_wpipe
  22.        wpipe::c_write_wpipe
  23.        wpipe::wait_wpipe_empty
  24.        wpipe::check_wpipe
  25.        wpipe::wpipe_free
  26.        wpipe::flush_wpipe
  27.        wpipe::get_bufsize
  28.        wpipe::get_filled
  29.        wpipe::get_flags
  30.  
  31. */
  32.  
  33. #include <stdio.h>
  34.  
  35. #include "task.hpp"
  36. #include "tsklocal.hpp"
  37.  
  38. /*
  39.    tsk_getwpipe - get a word from a pipe. For internal use only.
  40.                   Critical section assumed entered.
  41. */
  42.  
  43. word wpipe::tsk_getwpipe (void)
  44. {
  45.    word c;
  46.  
  47.    c = wcontents [outptr++];
  48.    if (outptr >= bufsize)
  49.       outptr = 0;
  50.    filled--;
  51.    return c;
  52. }
  53.  
  54.  
  55. /*
  56.    tsk_putwpipe - put a word to a pipe. For internal use only.
  57.                   Critical section assumed entered.
  58. */
  59.  
  60. void wpipe::tsk_putwpipe (word c)
  61. {
  62.    wcontents [inptr++] = c;
  63.    if (inptr >= bufsize)
  64.       inptr = 0;
  65.    filled++;
  66. }
  67.  
  68.  
  69. /* -------------------------------------------------------------------- */
  70.  
  71.  
  72. /*
  73.    wpipe - initialises wpipe.
  74. */
  75.  
  76. wpipe::wpipe (farptr buf, word buffersize)
  77. {
  78.    flags = 0;
  79.  
  80.    wait_read = wait_write = wait_clear = NULL;
  81.    outptr = inptr = filled = 0;
  82.    bufsize = buffersize >> 1;
  83.    wcontents = (wordptr)buf;
  84. }
  85.  
  86.  
  87. /*
  88.    ~wpipe - kills all processes waiting for reading from or writing
  89.                   to the wpipe.
  90. */
  91.  
  92. wpipe::~wpipe ()
  93. {
  94.    CRITICAL;
  95.  
  96.    C_ENTER;
  97.    tsk_kill_queue (&wait_read);
  98.    tsk_kill_queue (&wait_write);
  99.    tsk_kill_queue (&wait_clear);
  100.    outptr = inptr = filled = 0;
  101.    C_LEAVE;
  102.  
  103. }
  104.  
  105.  
  106. /*
  107.    read_wpipe - Wait until a word is written to the wpipe. If there 
  108.                 is a word in the wpipe on entry, it is assigned to 
  109.                 the caller, and the task continues to run. If there are
  110.                 tasks waiting to write, the first task is made eligible,
  111.                 and the word is inserted into the wpipe.
  112. */
  113.  
  114. word far wpipe::read_wpipe (dword timeout)
  115. {
  116.    tcbptr curr;
  117.    word res;
  118.    CRITICAL;
  119.  
  120.    C_ENTER;
  121.  
  122.    if (filled)
  123.       {
  124.       res = tsk_getwpipe ();
  125.  
  126.       if ((curr = wait_write) != NULL)
  127.          {
  128.          tsk_putwpipe (curr->get_retsize());
  129.          wait_write = curr->tsk_runable ();
  130.          curr->set_retptr(NULL);
  131.          }
  132.       else if (!filled)
  133.          while (wait_clear != NULL)
  134.             wait_clear = wait_clear->tsk_runable ();
  135.  
  136.       C_LEAVE;
  137.       return res;
  138.       }
  139.  
  140.    tsk_wait (&wait_read, timeout);
  141.    return (word)tsk_current->get_retptr();
  142. }
  143.  
  144.  
  145. /*
  146.    c_read_wpipe - If there is a word in the wpipe on entry,
  147.                   read_wpipe is called, otherwise an error status is returned.
  148. */
  149.  
  150. word far wpipe::c_read_wpipe (void)
  151. {
  152.    CRITICAL, res;
  153.  
  154.    C_ENTER;
  155.    res = (filled) ? read_wpipe (0L) : (word)-1;
  156.    C_LEAVE;
  157.    return res;
  158. }
  159.  
  160.  
  161.  
  162. /*
  163.    write_wpipe - Wait until space for the word to be written to the 
  164.                  wpipe is available. If there is enough space in the wpipe 
  165.                  on entry, the word is inserted into the wpipe, and
  166.                  the task continues to run. If there are tasks waiting 
  167.                  to read, the first task is made eligible, and the word
  168.                  is passed to the waiting task.
  169. */
  170.  
  171. int far wpipe::write_wpipe (word ch, dword timeout)
  172. {
  173.    tcbptr curr;
  174.    CRITICAL;
  175.  
  176.    C_ENTER;
  177.  
  178.    if (filled < bufsize)
  179.       {
  180.       if ((curr = wait_read) != NULL)
  181.          {
  182.          wait_read = curr->tsk_runable ();
  183.          curr->set_retptr((farptr)ch);
  184.          C_LEAVE;
  185.          return 0;
  186.          }
  187.  
  188.       tsk_putwpipe (ch);
  189.       C_LEAVE;
  190.       return 0;
  191.       }
  192.  
  193.    tsk_current->set_retsize(ch);
  194.    tsk_wait (&wait_write, timeout);
  195.    return (int)tsk_current->get_retptr();
  196. }
  197.  
  198.  
  199. /*
  200.    c_write_wpipe - If there is space for the word in the wpipe on entry,
  201.                    write_wpipe is called, otherwise an error status is returned.
  202. */
  203.  
  204. int far wpipe::c_write_wpipe (word ch)
  205. {
  206.    int res;
  207.    CRITICAL;
  208.  
  209.    C_ENTER;
  210.    res = (filled < bufsize) ? write_wpipe (ch, 0L) : -1;
  211.    C_LEAVE;
  212.    return res;
  213. }
  214.  
  215.  
  216. /*
  217.    wait_wpipe_empty - Wait until the pipe is empty. If the pipe is
  218.                       empty on entry, the task continues to run.
  219. */
  220.  
  221. int far wpipe::wait_wpipe_empty (dword timeout)
  222. {
  223.    CRITICAL;
  224.  
  225.    C_ENTER;
  226.    if (!filled)
  227.       {
  228.       C_LEAVE;
  229.       return 0;
  230.       }
  231.  
  232.    tsk_current->set_retptr(NULL);
  233.    tsk_wait (&wait_clear, timeout);
  234.    return (int)tsk_current->get_retptr();
  235. }
  236.  
  237.  
  238. /*
  239.    check_wpipe - returns -1 if there are no words in the wpipe, else
  240.                  the first available word.
  241. */
  242.  
  243. word far wpipe::check_wpipe (void)
  244. {
  245.    return (filled) ? wcontents [outptr] : (word)-1;
  246. }
  247.  
  248.  
  249. /*
  250.    wpipe_free - returns the number of free words in the pipe.
  251. */
  252.  
  253. word far wpipe::wpipe_free (void)
  254. {
  255.    return bufsize - filled;
  256. }
  257.  
  258. /*
  259.    flush_wpipe - Empty the pipe buffer, activate tasks waiting for 
  260.                  pipe clear.
  261. */
  262.  
  263. void far wpipe::flush_wpipe (void)
  264. {
  265.    CRITICAL;
  266.  
  267.    C_ENTER;
  268.    inptr = outptr = filled = 0;
  269.  
  270.    while (wait_clear != NULL)
  271.       wait_clear = wait_clear->tsk_runable ();
  272.    C_LEAVE;
  273. }
  274.  
  275.  
  276.  
  277. word far asm_read_wpipe(wpipeptr pip, dword timeout)
  278. {
  279.     return pip->read_wpipe(timeout);
  280. }
  281.  
  282. word far asm_check_wpipe(wpipeptr pip)
  283. {
  284.     return pip->check_wpipe();
  285. }
  286.  
  287. int far asm_c_write_wpipe(wpipeptr pip, word ch)
  288. {
  289.     return pip->c_write_wpipe(ch);
  290. }
  291.  
  292.